﻿using Protocol;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using Atom.NetFrame;

namespace Atom.Logic.Fight
{
    class TestFightRoom
    {

        private List<UserToken> m_UserTockens = new List<UserToken>();
        private List<int> m_PlayerIds = new List<int>();
        private ConcurrentDictionary<int, List<InputCommand>> m_Frame2Inputs = new ConcurrentDictionary<int, List<InputCommand>>();

        private int m_MaxPlayerCount = 2;
        private TimeManager m_TimeManager;
        private bool m_IsRunning;
        private long m_GameStartTimestampMs = 0;
        private int m_SendTick;

        public void Init()
        {
            m_TimeManager = new TimeManager();
        }

        public void MessageReceive(UserToken ut, SocketModel message)
        {
            switch (message.Command)
            {
                case FightProtocol.ENTER_GAMESCENE_REQ:
                    EnterGameScene(ut);
                    break;
                case FightProtocol.INPUT_REQ:
                    Input(ut, message);
                    break;

            }
        }

        public void DoTick()
        {

        }

        public void EnterGameScene(UserToken ut)
        {
            Console.WriteLine("-------------------------------玩家进入游戏------------------------------");
            m_UserTockens.Add(ut);   
            if (m_UserTockens.Count >= m_MaxPlayerCount)
            {
                Broadcast(FightProtocol.START_GAME_RES, null);
                m_IsRunning = true;
                m_TimeManager.Start();
                m_GameStartTimestampMs = 0;
                Console.WriteLine("-------------------------------战斗开始------------------------------");
            }

        }

        /// <summary>
        ///  输入
        /// </summary>
        /// <param name="ut"></param>
        /// <param name="message"></param>
        public void Input(UserToken ut, SocketModel message)
        {

            ReqPlayerInput input = ReqPlayerInput.Decode(message.Message);

            if (m_PlayerIds.Count != m_MaxPlayerCount)
            {
                if (!m_PlayerIds.Contains(input.InputCommand.PlayerId))
                {
                    m_PlayerIds.Add(input.InputCommand.PlayerId);
                }
            }

            if (!m_Frame2Inputs.ContainsKey(input.LogicFrame))
            {
                List<InputCommand> inputs = new List<InputCommand>();
                m_Frame2Inputs.TryAdd(input.LogicFrame, inputs);
            }

            //// 输入已经塞满，这个命令可能发过来太迟了，被空命令填充掉了
            //if (m_Frame2Inputs[input.LogicFrame].Count >= m_MaxPlayerCount)
            //{
            //    Console.WriteLine("命令已经丢弃");
            //    return;
            //}
            //if (m_Frame2Inputs[input.LogicFrame].Contains(input.InputCommand))
            //{
            //    Console.WriteLine("冗余的命令");
            //    return;
            //}
            m_Frame2Inputs[input.LogicFrame].Add(input.InputCommand);

            if (m_Frame2Inputs[input.LogicFrame].Count == m_MaxPlayerCount)
            {
                ResInputMessage res = new ResInputMessage();
                res.LogicFrame = input.LogicFrame;
                res.Cmds.AddRange(m_Frame2Inputs[input.LogicFrame]);
                Broadcast(FightProtocol.INPUT_RES, res.Encode());
                Console.WriteLine("发送");
            }
        }


        /// <summary>
        /// 检查是否所有人都输入完毕
        /// </summary>
        /// <returns></returns>
        public bool CheckFullInput(bool isForce, int sendTick)
        {
            //已经发过了
            if (sendTick < m_SendTick)
            {
                Console.WriteLine("已经发过了");
                return false;
            }
            // 是否已经有收到过这个tick的输入
            if (!m_Frame2Inputs.ContainsKey(sendTick))
            {
                if (!isForce)
                {
                    return false;
                }
                else
                {
                    // 强制发送
                    Console.WriteLine("强制发送");
                    List<InputCommand> emptyInputs = new List<InputCommand>();
                    foreach (var item in m_PlayerIds)
                    {
                        InputCommand c = new InputCommand();
                        c.PlayerId = item;
                        emptyInputs.Add(c);
                    }
                    m_Frame2Inputs.TryAdd(sendTick, emptyInputs);
                }
            }

            //查看有没有没收到的
            if (m_Frame2Inputs[sendTick].Count < m_MaxPlayerCount)
            {
                if (isForce)
                {
                    foreach (var item1 in m_PlayerIds)
                    {
                        bool hasMatch = false;
                        foreach (var item2 in m_Frame2Inputs[sendTick])
                        {
                            if (item1 == item2.PlayerId)
                            {
                                hasMatch = true;
                            }
                        }
                        if (hasMatch == false)
                        {
                            InputCommand emptyInput = new InputCommand();
                            m_Frame2Inputs[sendTick].Add(emptyInput);
                        }
                    }
                }
                else
                {
                    return false;
                }

            }
            m_SendTick = sendTick;
            return true;

        }
        public void FrameLogic()
        {
            if (!m_IsRunning) return;
            ResInputMessage res = new ResInputMessage();
            res.LogicFrame = m_SendTick;
            res.Cmds.AddRange(m_Frame2Inputs[m_SendTick]);
            Broadcast(FightProtocol.INPUT_RES, res.Encode());
        }

        public void Broadcast(int command, byte[] message)
        {
            SocketModel sm = new SocketModel(GameProtocol.TYPE_FIGHT, 0, command, message);
            foreach (var item in m_UserTockens)
            {
                item.SendMsg(sm.Encode());
            }
        }
    }
}
